
class X {
    Set keysForValues = ['size', 'weight']
    private Map values = [:]
    //Intentionally not including values in the set of props. We don't want values to be accessed directly.
    Set props = ['myVar']
    def myVar;

    def getProperty(String key){
        if(keysForValues.contains(key))
            return values[key]
       else if(props.contains(key))
           return  this.@"${key}"
       else{}
        //Don't throw exception here, or some weird groovy things could happen.
        //For example,  x.@"${varName}" could fail  
    }

   public void setProperty(String key, Object value){
         if(keysForValues.contains(key))
            values[key] = value
        else if(props.contains(key))
            this.@"${key}" = value
         else{}
        //Don't throw exception here, or some weird groovy things could happen.

   }
        
}

def x = new X()
x.size  = 7
println x.size

x.myVar = 43
println x.myVar



x.@myVar = 5


println x.@myVar

println x.'myVar'

println 'right here'
println x.@'myVar'
def varName = 'myVar'

println 'using String variables to access property methods'
x."${varName}" = 8
println x."${varName}"
x.@"${varName}" = 0
println x.@"${varName}"


//This results in null
println x.properties

println 'Now working with a regular class'
class Hi{

}
def hi = new Hi()
println hi.properties



println x.props.getClass().getName()
println x.props
